/**
 * Author: ZhangYang
 * Version: 1.01
 */

package com.pccw.portlet.util.excel.exportutil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

//import com.liferay.portal.util.LiveUsers;
import com.pccw.portlet.util.PccwCommonUtil;
import com.pccw.portlet.util.excel.Constants;
import com.pccw.portlet.util.excel.ExcelStye;
import com.pccw.portlet.util.excel.ExcelUtil;

public class ComplexTemplateExporter {

	/*
	 * ���������ļ���Ӧ������Sheet��
	 * ��һ��Sheet�ĸ�ʽ�뵼��ģ����ͬ����Ҫ������ݵĵ�Ԫ��������ע��Ϣ���������õ�������
	 * �ڶ���SheetΪ����ȫ������
	 * 
	 * ģ���ļ���Ϊ��ʽ�Ĺ��û�������EXCELģ���ʽ
	 */
	private String templateFilePath = null; // ����ģ���ļ���·��
	private String ruleFilePath = null; // ���������ļ���·��
	private String exportFilePath = null; // ������ݺ�������ļ���·��

	private short defaultColumnWidth = 0;
	private boolean autoAdjustUndefinedColumnWidth = true;
	private int lineType = 0;
	
	private HSSFWorkbook workbook = new HSSFWorkbook();
	private HSSFSheet currentSheet = null;
	private int currentSheetId = 0;
	private List errorList = new ArrayList();
	
	private TemplateExportRule templateExportRule = new TemplateExportRule(); // ���ģ��ĵ�������ȫ������
	private Map headDataRuleMap; //���ڱ����ģ���ж�ȡ������ͷ��Ϣ��ݵ�������
	private Map detailDataRuleMap; //���ڱ����ģ���ж�ȡ��������ϸ��Ϣ��ݵ�������
	
	private boolean initResult = true; // ���ڱ����ʼ�������Ƿ�ɹ�
	
	private Map styleMap = new HashMap();
	
	
	//private   static  String DATE_FORMAT_DATA  =   "yyyy-mm-dd" ;
	//private   static  String DATE_FORMAT_NUM  =   "0.00000000_);[��ɫ](0.00000000)" ;
	private ExcelStye es = new ExcelStye();
//	{
//		format_date  =  workbook.createCellStyle();
//		HSSFDataFormat format  =  workbook.createDataFormat(); 
//		format_date.setDataFormat(format.getFormat(DATE_FORMAT_DATA)); 
//		
//		format_num  =  workbook.createCellStyle();
//		format  =  workbook.createDataFormat(); 
//		format_num.setDataFormat(format.getFormat(DATE_FORMAT_NUM));	
//		
//	};
	
	
	
	/**
	 * Constructor
	 */
	public ComplexTemplateExporter(String ruleFilePath, String templateFilePath, String exportFilePath){
		this.templateFilePath = templateFilePath;
		this.exportFilePath = exportFilePath;
		this.ruleFilePath = ruleFilePath;
		
		File file = null;
		FileInputStream fis = null;
		try {
			file = new File(templateFilePath);
			if(file != null){
				fis = new FileInputStream(file);
				// ��Ҫ������EXCEL�ļ��������һ��workbook
				workbook = new HSSFWorkbook(fis);
				if(workbook != null){
					this.currentSheet = workbook.getSheetAt(0);
				}
			}
			this.es = new ExcelStye(workbook);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	
	
	/**
	 * ��ʼ�������ص�������
	 */
	public boolean init(){
		if(this.ruleFilePath == null || this.workbook == null){
			return false;
		}
		
		boolean result = this.loadExportRules();
		if(result == true){
			// this.printRules(); // (*)�ڿ���̨��ӡ�����Ѽ��ص���֤���򣬲�����
		}
		
		this.initResult = result;
		
		return result;
	}
	
	/**
	 * �������ݵ�Workbook����д��EXCEL�ļ�
	 */
	public File getExportedFile(){
		if(this.workbook == null){
			return null;
		}
		
		if(this.workbook.getNumberOfSheets() > 1){
			this.workbook.removeSheetAt(0); // ɾ��ԭ�еĵ�һ���հ׵ĵ���ģ��
			this.currentSheetId--;
		}
		
		// ɾ��������Ŀհ�ģ��
		int numberOfSheets = this.workbook.getNumberOfSheets();
		for(int i = this.currentSheetId + 1; i < numberOfSheets; i++){
			this.workbook.removeSheetAt(this.workbook.getNumberOfSheets() - 1); // ÿ�ζ�ɾ�����һ��Sheet
		}
		
		// ����һ��Sheet����Ϊ��ǰ�Sheet
		this.currentSheet = this.workbook.getSheetAt(0);
		this.currentSheet.setSelected(true);
		File outFile = new File(this.exportFilePath);
		if(outFile == null){
			return null;
		}
		if(outFile.exists() == false){
			try {
				outFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(outFile);
			this.workbook.write(fos);
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
            try {
                if (fos != null)
                	fos.close();
            } catch (IOException e) {
            }
        }
		
		return outFile;
	}
	

	/**
	 * ������֤����
	 * �ӹ��췽�����ݽ�����ģ���ļ��ж�ȡ��ص���֤�������
	 */
	private boolean loadExportRules(){
		// �������ļ�δָ�������޷�������֤����
		if(this.ruleFilePath == null){
			return false;
		}
		
		// ��ݹ����ļ�����չ����ȷ���ú��ֹ������ʵ��������ȡ��֤����
		if(this.ruleFilePath == null || "".equals(this.ruleFilePath) || this.ruleFilePath.indexOf(".") == -1){
			return false;
		}
		
		ExportRuleLoader ruleLoader = null; // ������֤����Ĺ�����
		
		String fileExt = this.ruleFilePath.substring(this.ruleFilePath.lastIndexOf("."));
		if(".xls".equalsIgnoreCase(fileExt)){
			ruleLoader = new ExportRuleExcelLoader();
		}
		else if(".xml".equalsIgnoreCase(fileExt)){
			ruleLoader = new ExportRuleXmlLoader();
		}
		else{
			this.errorList.add(Constants.UNKNOWN_EXPORT_RULE_TEMPLATE_FILE_FORMAT);
			return false;
		}
		
		boolean ruleLoaded = ruleLoader.loadExportRules(this.ruleFilePath);
		if( ! ruleLoaded){
			// �ڿ���̨��ӡ������֤�������������Ĵ�����ʾ��Ϣ
			List loadRuleErrors = ruleLoader.getErrorList();
			if(loadRuleErrors != null && loadRuleErrors.size() > 0){
				for(int i = 0; i < loadRuleErrors.size(); i++){
					System.out.println("error when loading export rule: " + loadRuleErrors.get(i));
				}
			}
			return false;
		}

		// 1.��ȡ���ģ��ĵ�������ȫ�����ã���װ��TemplateExportRule����
		this.templateExportRule = ruleLoader.getTemplateExportRule();
		
		// 2.��ȡͷ��Ϣ��ݵĵ�������
		this.headDataRuleMap = ruleLoader.getHeadDataRuleMap();
		
		// 3.��ȡ��ϸ��Ϣ��ݵĵ�������
		this.detailDataRuleMap = ruleLoader.getDetailDataRuleMap();
		
		return true;
	}
	
	/**
	 * ��ǰSheetͷ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�String��, Edited on 2008-01-11
	 */
	public boolean setHeadItemValue(String itemName, String itemValue){
		return this.setHeadItemValueByObject(itemName, itemValue);
	}
	
	/**
	 * ��ǰSheetͷ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Date��, Added on 2008-01-11
	 */
	public boolean setHeadItemValue(String itemName, Date itemValue){
		return this.setHeadItemValueByObject(itemName, itemValue);
	}
	
	/**
	 * ��ǰSheetͷ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Number��, Added on 2008-01-11
	 */
	public boolean setHeadItemValue(String itemName, Number itemValue){
		return this.setHeadItemValueByObject(itemName, itemValue);
	}
	
	/**
	 * ��ǰSheetͷ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Object��Added on 2008-01-11
	 */
	private boolean setHeadItemValueByObject(String itemName, Object itemValue){
		if(this.headDataRuleMap == null || this.headDataRuleMap.size() == 0){
			return false;
		}
		
		boolean result = true;
		
		if(this.currentSheet == null){
			int sheetId = 1;
			if(this.currentSheetId > 1){
				sheetId = this.currentSheetId;
			}
			this.currentSheet = this.workbook.getSheetAt(sheetId);
			
			if(this.currentSheet == null){
				this.createNewSheet("Auto-Created-Sheet");
			}
		}
		
		CellExportRule rule = (CellExportRule)this.headDataRuleMap.get(itemName);
		
		if(rule == null){
			result = false;
		}
		else{
			HSSFCell cell = ExcelUtil.getCell(this.currentSheet, rule.getRowId(), rule.getColumnId());
			if(cell == null){
				result = false;
			}
			else{
				result = setCellValueWithFormat(cell, itemValue, rule.getCellFormat());
			}
		}

		return result;
	}
	
	/**
	 * ��ǰSheet��ϸ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�String��, Edited on 2008-01-11
	 */
	public boolean setDetailItemValue(int lineId, String itemName, String itemValue){
		return setDetailItemValueByObject(lineId, itemName, itemValue);
	}
	
	/**
	 * ��ǰSheet��ϸ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Date��, Added on 2008-01-11
	 */
	public boolean setDetailItemValue(int lineId, String itemName, Date itemValue){
		return setDetailItemValueByObject(lineId, itemName, itemValue);
	}
	
	/**
	 * ��ǰSheet��ϸ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Number��, Added on 2008-01-11
	 */
	public boolean setDetailItemValue(int lineId, String itemName, Number itemValue){
		return setDetailItemValueByObject(lineId, itemName, itemValue);
	}
	
	/**
	 * ��ǰSheet��ϸ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ���������ͣ�,�������ƶ����� Added on 2008-01-11
	 */
	public boolean setDetailItemValue(int lineId, String itemName, Object itemValue,String type){
		return setDetailItemValueByObject(lineId, itemName, itemValue,type);
	}
	
	/**
	 * ��ǰSheet��ϸ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Object��, Added on 2008-01-11
	 */
	private boolean setDetailItemValueByObject(int lineId, String itemName, Object itemValue){
		if(this.detailDataRuleMap == null || this.detailDataRuleMap.size() == 0){
			return false;
		}
		
		boolean result = true;
		
		if(this.currentSheet == null){
			int sheetId = 1;
			if(this.currentSheetId > 1){
				sheetId = this.currentSheetId;
			}
			this.currentSheet = this.workbook.getSheetAt(sheetId);
			
			if(this.currentSheet == null){
				this.createNewSheet("Auto-Created-Sheet");
			}
		}
		
		CellExportRule rule = (CellExportRule)this.detailDataRuleMap.get(itemName);
		
		if(rule == null){
			result = false;
		}
		else{
			HSSFCell cell = this.getDetailCellOfSheet(this.currentSheet, lineId, rule);
			if(cell == null){
				result = false;
			}
			else{
				//System.out.println("lineId="+lineId);
				int rowId = this.getDetailCellRowId(this.currentSheet, lineId, rule);
				//System.out.println("rowId="+rowId);
				short columnId = this.getDetailCellColumnId(this.currentSheet, lineId, rule);
				//==================================================================================================================
				result = setCellValueWithFormat(this.currentSheet,rowId,columnId,cell, itemValue, rule.getCellFormat(),"none");
				//result = setCellValueWithFormat(this.currentSheet,lineId,columnId,cell, itemValue, rule.getCellFormat());
			}
		}
		
		//System.out.println(rule.getCellName() + ": " + itemValue + ", format: " + rule.getCellFormat() + ", result: " + result); // (*), ������

		return result;
	}
	
	
	/**
	 * ��ǰSheet��ϸ��Ϣ��ĳһ���ĳһ��Ԫ�񣩸�ֵ��ֵ���ͣ�Object��, �������ƶ����� Added on 2008-01-11
	 */
	private boolean setDetailItemValueByObject(int lineId, String itemName, Object itemValue,String type){
		if(this.detailDataRuleMap == null || this.detailDataRuleMap.size() == 0){
			return false;
		}
		
		boolean result = true;
		
		if(this.currentSheet == null){
			int sheetId = 1;
			if(this.currentSheetId > 1){
				sheetId = this.currentSheetId;
			}
			this.currentSheet = this.workbook.getSheetAt(sheetId);
			
			if(this.currentSheet == null){
				this.createNewSheet("Auto-Created-Sheet");
			}
		}
		
		CellExportRule rule = (CellExportRule)this.detailDataRuleMap.get(itemName);
		
		if(rule == null){
			result = false;
		}
		else{
			HSSFCell cell = this.getDetailCellOfSheet(this.currentSheet, lineId, rule);
			if(cell == null){
				result = false;
			}
			else{
				//System.out.println("lineId="+lineId);
				int rowId = this.getDetailCellRowId(this.currentSheet, lineId, rule);
				//System.out.println("rowId="+rowId);
				short columnId = this.getDetailCellColumnId(this.currentSheet, lineId, rule);
				//==================================================================================================================
				result = setCellValueWithFormat(this.currentSheet,rowId,columnId,cell, itemValue, rule.getCellFormat(),type);
				//result = setCellValueWithFormat(this.currentSheet,lineId,columnId,cell, itemValue, rule.getCellFormat());
			}
		}
		
		//System.out.println(rule.getCellName() + ": " + itemValue + ", format: " + rule.getCellFormat() + ", result: " + result); // (*), ������

		return result;
	}
	
	/**
	 * ���ָ���ĸ�ʽ��һ����Ԫ��ֵ, Added on 2008-01-10
	 */
	private boolean setCellValueWithFormat(HSSFSheet sheet, int rowId, short columnId,HSSFCell cell, Object value, String cellFormat,String type){
		if(cell == null){
			return false;
		}
		
		
		
		boolean result = true;
		if("none".equals(type)){
			if(cellFormat == null || cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_GENERAL)){
				result = this.setCellValueWithFormatOfGeneral(cell, value);
			}
			else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_TEXT)){
				result = this.setCellValueWithFormatOfText(cell, value);
			}
			else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_NUMERIC)){
				//===========================================================================================
				//��ÿһ�еĸ�ʽ����һ��map����
				if(this.styleMap.get("format") == null){
	//				for(short i=0;i<Short.parseShort(lastCellNum);i++){
	//					HSSFCellStyle cellStyle  =  workbook.createCellStyle();
	//					cellStyle.setDataFormat(sheet.getRow(rowId-1).getCell(i).getCellStyle().getDataFormat());
	//					this.styleMap.put(new Short(i).toString(), cellStyle);
	//					System.out.println("i="+i);
	//				}
	//				this.styleMap.put("format", "Y");
					short i = 0;
					HSSFCell tempCell = sheet.getRow(rowId-1).getCell(i);
					while(tempCell != null){
						HSSFCellStyle cellStyle  =  workbook.createCellStyle();
						cellStyle.setDataFormat(tempCell.getCellStyle().getDataFormat());
						this.styleMap.put(new Short(i).toString(), cellStyle);
						//System.out.println("i="+tempCell.getStringCellValue());
						//System.out.println("tempCell.getCellStyle().getDataFormat()="+tempCell.getCellStyle().getDataFormat());
						i++;
						tempCell = sheet.getRow(rowId-1).getCell(i);
					}
					this.styleMap.put("format", "Y");
				}
				//cell.setCellStyle((HSSFCellStyle)this.styleMap.get(columnIdStr));
				//===========================================================================================
				result = this.setCellValueWithFormatOfNumeric(sheet,rowId,columnId,cell, value);
			}
			else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_DATE)){
				result = this.setCellValueWithFormatOfDate(cell, value);
			}
			else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_AUTO)){
				result = this.setCellValueWithFormatOfAuto(cell, value);
			}
			else{
				result = false; // cellFormatΪ��֧�ֵĸ�ʽ����
			}
		}else if("Double".equals(type)){
			cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
			cell.setCellValue(Double.parseDouble(value.toString()));
			result = true;
		}else if("Double2".equals(type)){
			HSSFDataFormat dataFormat = workbook.createDataFormat();
			cell.getCellStyle().setDataFormat(dataFormat.getFormat("0.00"));
			cell.setCellValue(Double.parseDouble(value.toString()));
			result = true;
		}else if("String".equals(type)){
			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
			cell.setCellValue(new HSSFRichTextString(value.toString()));
			result = true;
		}else{
			result = false;
		}
		return result;
	}
	
	/**
	 * ���ָ���ĸ�ʽ��һ����Ԫ��ֵ, Added on 2008-01-10
	 */
	private boolean setCellValueWithFormat(HSSFCell cell, Object value, String cellFormat){
		if(cell == null){
			return false;
		}
		
		boolean result = true;
		
		if(cellFormat == null || cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_GENERAL)){
			result = this.setCellValueWithFormatOfGeneral(cell, value);
		}
		else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_TEXT)){
			result = this.setCellValueWithFormatOfText(cell, value);
		}
		else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_NUMERIC)){
			result = this.setCellValueWithFormatOfNumeric(cell, value);
		}
		else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_DATE)){
			result = this.setCellValueWithFormatOfDate(cell, value);
		}
		else if(cellFormat.equalsIgnoreCase(CellExportRule.CELL_FORMAT_OF_AUTO)){
			result = this.setCellValueWithFormatOfAuto(cell, value);
		}
		else{
			result = false; // cellFormatΪ��֧�ֵĸ�ʽ����
		}
		
		return result;
	}
	
	/**
	 * ��һ����Ԫ��ֵ�������ʽ��, Added on 2008-01-11
	 */
	private boolean setCellValueWithFormatOfGeneral(HSSFCell cell, Object value){
		if(cell == null){
			return false;
		}

		boolean result = true;
		//HSSFCellStyle style = workbook.createCellStyle(); // (*)�����ַ�ʽ���ԭ��Ԫ���һЩ��ʽ�������ݲ�ʹ�ã�
		HSSFCellStyle style = cell.getCellStyle();
		style.setDataFormat(ExcelUtil.EXCEL_FORMAT_CODE_OF_GENERAL); // ����Ԫ���ʽ����Ϊ"����"
		cell.setCellStyle(style);
		
		if(value == null){
			cell.setCellValue(new HSSFRichTextString(""));
		}
		else if(value instanceof String){
			cell.setCellValue(new HSSFRichTextString((String)value));
		}
		else if(value instanceof Number){
			Double doubleValue = PccwCommonUtil.getDoubleObjectFromString(value.toString());
			if(doubleValue != null){
				cell.setCellValue(doubleValue.doubleValue());
			}
			else{
				result = false;
			}
		}
		else if(value instanceof Date){
			cell.setCellValue((Date)value);
		}
		else{
			result = false; // valueΪ��֧�ֵ�����
		}

		return result;
	}
	
	/**
	 * ��һ����Ԫ��ֵ���ı���ʽ��, Added on 2008-01-11
	 */
	private boolean setCellValueWithFormatOfText(HSSFCell cell, Object value){
		if(cell == null){
			return false;
		}

		boolean result = true;
		//HSSFCellStyle style = workbook.createCellStyle(); (*)�����ַ�ʽ���ԭ��Ԫ���һЩ��ʽ�������ݲ�ʹ�ã�
		HSSFCellStyle style = cell.getCellStyle();
		style.setDataFormat(ExcelUtil.EXCEL_FORMAT_CODE_OF_TEXT); // ����Ԫ���ʽ����Ϊ"�ı�"
		cell.setCellStyle(style);
		
		if(value == null){
			cell.setCellValue(new HSSFRichTextString(""));
		}
		else if(value instanceof String){
			cell.setCellValue(new HSSFRichTextString((String)value));
		}
		else if(value instanceof Number){
			cell.setCellValue(new HSSFRichTextString(value.toString()));
		}
		else if(value instanceof Date){
			cell.setCellValue(new HSSFRichTextString(
					PccwCommonUtil.getCommonDateString(((Date)value).getTime())));
		}
		else{
			result = false; // valueΪ��֧�ֵ�����
		}

		return result;
	}
	
	/**
	 * ��һ����Ԫ��ֵ����ֵ��ʽ��, Added on 2008-01-11
	 */
	private boolean setCellValueWithFormatOfNumeric(HSSFSheet sheet, int rowId, short columnId,HSSFCell cell, Object value){
		if(cell == null){
			return false;
		}

		boolean result = true;
		//HSSFCellStyle style = workbook.createCellStyle(); (*)�����ַ�ʽ���ԭ��Ԫ���һЩ��ʽ�������ݲ�ʹ�ã�
		//===========================================================================================
		String columnIdStr = new Short(columnId).toString();
		if(this.styleMap.get(columnIdStr) == null){
			HSSFCellStyle cellStyle  =  workbook.createCellStyle();
			cellStyle.setDataFormat(sheet.getRow(rowId-1).getCell(columnId).getCellStyle().getDataFormat());
			this.styleMap.put(columnIdStr, cellStyle);
			//System.out.println("create="+columnId);
		}
		cell.setCellStyle((HSSFCellStyle)this.styleMap.get(columnIdStr));
		//===========================================================================================
		
		
		Double doubleValue = null;
		
		if(value == null){
			cell.setCellValue(new HSSFRichTextString(""));
		}
		else if(value instanceof String){
			try{
				doubleValue = Double.valueOf((String)value);
			}
			catch(Exception e){
			}
			
			if(doubleValue != null){
				cell.setCellValue(doubleValue.doubleValue());
			}
			else{
				result = false;
			}
		}
		else if(value instanceof Number){
			doubleValue = PccwCommonUtil.getDoubleObjectFromString(value.toString());
			if(doubleValue != null){
				cell.setCellValue(doubleValue.doubleValue());
			}
			else{
				result = false;
			}
		}
		else if(value instanceof Date){
			cell.setCellValue(((Date)value).getTime());
		}
		else{
			result = false; // valueΪ��֧�ֵ�����
		}

		return result;
	}
	
	/**
	 * ��һ����Ԫ��ֵ����ֵ��ʽ��, Added on 2008-01-11
	 */
	private boolean setCellValueWithFormatOfNumeric(HSSFCell cell, Object value){
		if(cell == null){
			return false;
		}

		boolean result = true;
		//HSSFCellStyle style = workbook.createCellStyle(); (*)�����ַ�ʽ���ԭ��Ԫ���һЩ��ʽ�������ݲ�ʹ�ã�
		//HSSFCellStyle cellStyle  =  workbook.createCellStyle();  //  �����µ�cell��ʽ 
       // HSSFDataFormat format  =  workbook.createDataFormat(); 
       // cellStyle.setDataFormat(format.getFormat(DATE_FORMAT_NUM));  // ����Ԫ���ʽ����Ϊ"����"
		//cell.setCellStyle(cellStyle);
		//cell.getCellStyle().setDataFormat(sheet.getRow(rowId-1).getCell(columnId).getCellStyle().getDataFormat());
		cell.setCellStyle(es.getFormat_num());
		Double doubleValue = null;
		
		if(value == null){
			cell.setCellValue(new HSSFRichTextString(""));
		}
		else if(value instanceof String){
			try{
				doubleValue = Double.valueOf((String)value);
			}
			catch(Exception e){
			}
			
			if(doubleValue != null){
				cell.setCellValue(doubleValue.doubleValue());
			}
			else{
				result = false;
			}
		}
		else if(value instanceof Number){
			doubleValue = PccwCommonUtil.getDoubleObjectFromString(value.toString());
			if(doubleValue != null){
				cell.setCellValue(doubleValue.doubleValue());
			}
			else{
				result = false;
			}
		}
		else if(value instanceof Date){
			cell.setCellValue(((Date)value).getTime());
		}
		else{
			result = false; // valueΪ��֧�ֵ�����
		}

		return result;
	}
	
	/**
	 * ��һ����Ԫ��ֵ�����ڸ�ʽ��, Added on 2008-01-11
	 */
	private boolean setCellValueWithFormatOfDate(HSSFCell cell, Object value){
		if(cell == null){
			return false;
		}

		boolean result = true;
		//HSSFCellStyle style = workbook.createCellStyle(); (*)�����ַ�ʽ���ԭ��Ԫ���һЩ��ʽ�������ݲ�ʹ�ã�
		HSSFCellStyle style = cell.getCellStyle();
		
		if(value == null){
			// �������ڸ�ʽ�ĵ�Ԫ�����?Ϊnullֵ�����Խ���Ԫ������Ϊ"����"��ʽ
			style.setDataFormat(ExcelUtil.EXCEL_FORMAT_CODE_OF_GENERAL);
			cell.setCellStyle(style);
			cell.setCellValue(new HSSFRichTextString(""));
		}
		else{
			//HSSFCellStyle cellStyle  =  workbook.createCellStyle();  //  �����µ�cell��ʽ 
	       //   HSSFDataFormat format  =  workbook.createDataFormat(); 
	       //   cellStyle.setDataFormat(format.getFormat(DATE_FORMAT_DATA));  // ����Ԫ���ʽ����Ϊ"����"
			//cell.setCellStyle(cellStyle);
			cell.setCellStyle(es.getFormat_date());
			
			if(value instanceof String){
				Date date = PccwCommonUtil.getJavaUtilDateFromDateString((String)value);
				if(date != null){
					cell.setCellValue(date);
				}
				else{
					result = false; // value��ֵ����ת����Date����
				}
			}
			else if(value instanceof Number){
				Date date = null;
				Long longValue = PccwCommonUtil.getLongObjectFromString(value.toString());
				if(longValue != null){
					date = new Date(longValue.longValue());
				}

				if(date != null){
					cell.setCellValue(date);
				}
				else{
					result = false; // value��ֵ����ת����Date����
				}
			}
			else if(value instanceof Date){
				cell.setCellValue((Date)value);
			}
			else{
				result = false; // valueΪ��֧�ֵ�����
			}
		}
		

		return result;
	}
	
	/**
	 * ��һ����Ԫ��ֵ�������ֵ��ʵ�������Զ����ø�ʽ��, Added on 2008-01-11
	 */
	private boolean setCellValueWithFormatOfAuto(HSSFCell cell, Object value){
		if(cell == null){
			return false;
		}

		boolean result = true;
		//HSSFCellStyle style = workbook.createCellStyle(); //(*)�����ַ�ʽ���ԭ��Ԫ���һЩ��ʽ�������ݲ�ʹ�ã�
		HSSFCellStyle style = cell.getCellStyle();
		
		if(value == null){
			style.setDataFormat(ExcelUtil.EXCEL_FORMAT_CODE_OF_GENERAL); // �Զ�����Ԫ���ʽ����Ϊ"����"
			cell.setCellStyle(style);
			cell.setCellValue(new HSSFRichTextString(""));
		}
		else if(value instanceof String){
			style.setDataFormat(ExcelUtil.EXCEL_FORMAT_CODE_OF_TEXT); // �Զ�����Ԫ���ʽ����Ϊ"�ı�"
			cell.setCellStyle(style);
			cell.setCellValue(new HSSFRichTextString((String)value));
		}
		else if(value instanceof Number){
			style.setDataFormat(ExcelUtil.EXCEL_FORMAT_CODE_OF_GENERAL); // �Զ�����Ԫ���ʽ����Ϊ"����"
			cell.setCellStyle(style);
			
			Double doubleValue = PccwCommonUtil.getDoubleObjectFromString(value.toString());
			if(doubleValue != null){
				cell.setCellValue(doubleValue.doubleValue());
			}
			else{
				result = false; // value��ֵ����ת����Double���ͣ���ת����String��
			}
		}
		else if(value instanceof Date){
			HSSFCellStyle cellStyle  =  workbook.createCellStyle();  //  �����µ�cell��ʽ 
	          HSSFDataFormat format  =  workbook.createDataFormat(); 
			cell.setCellStyle(style);
			cell.setCellValue((Date)value);
		}
		else{
			result = false; // valueΪ��֧�ֵ�����
		}

		return result;
	}

	/**
	 * ����һ����Sheet����һ�����Rowʱ����ԭSheet�Ѵﵽ�������ʱ����
	 * �����Զ�clone sheet����Ҫ�ڵ���ģ����Ԥ�ȴ����������Sheet
	 */
	public boolean createNewSheet_old(String sheetName){
		if(sheetName == null){
			return false;
		}
		
		boolean result = true;

		// �жϸ���Ƶ�Sheet�Ƿ��Ѿ����ڣ�����Ѿ��������ڸ���ƺ���������ֺ�׺
		HSSFSheet sheet = this.workbook.getSheet(sheetName);
		int plusId = 1;
		String plusName = "";
		while(sheet != null){
			plusId++;
			sheet = this.workbook.getSheet(sheetName + plusId);
		}
		
		if(plusId > 1){
			plusName = "" + plusId;
		}
		
		//this.currentSheet = this.workbook.cloneSheet(0); // ������쳣
		//this.currentSheetId = this.workbook.getNumberOfSheets() - 1;
		
		if((this.currentSheetId + 1) < this.workbook.getNumberOfSheets()){
			this.currentSheet = this.workbook.getSheetAt(this.currentSheetId + 1);
			this.workbook.setSheetName(this.currentSheetId + 1, sheetName + plusName);
			this.currentSheetId++;
		}
		else{
			this.currentSheet = this.workbook.createSheet(sheetName + plusName);
			this.currentSheetId = this.workbook.getNumberOfSheets() - 1;
		}
		
		return result;
	}
	
	/**
	 * ����һ����Sheet����һ�����Rowʱ����ԭSheet�Ѵﵽ�������ʱ����
	 * use clone sheet
	 */
	public boolean createNewSheet(String sheetName){
		if(sheetName == null){
			return false;
		}
		
		boolean result = true;
		
		// ȥ��Sheet����в�����������ַ�/, \, *, ?, [, ]����2007-09-25���
		sheetName = sheetName.replace('/', '-');
		sheetName = sheetName.replace('\\', '-');
		sheetName = sheetName.replace('*', '-');
		sheetName = sheetName.replace('?', '-');
		sheetName = sheetName.replace('[', '-');
		sheetName = sheetName.replace(']', '-');
		
		// ����POI������Sheet��Ƴ���31���ַ���Ҳ��1�����㣩�����ǵ����滹���ܸ�Sheet��Ƽ����ֺ�׺���˴����Ʋ����?��29���ַ�2007-09-25���
		if(sheetName.length() > 29){
			sheetName = sheetName.substring(0, 29);
		}

		// �жϸ���Ƶ�Sheet�Ƿ��Ѿ����ڣ�����Ѿ��������ڸ���ƺ���������ֺ�׺
		HSSFSheet sheet = this.workbook.getSheet(sheetName);
		int plusId = 1;
		String plusName = "";
		while(sheet != null){
			plusId++;
			sheet = this.workbook.getSheet(sheetName + plusId);
		}
		
		if(plusId > 1){
			plusName = "" + plusId;
		}
		
		this.currentSheet = this.workbook.cloneSheet(0); // ������쳣
		this.currentSheetId = this.workbook.getNumberOfSheets() - 1; // ����ǰSheetId��λ����clone��������Sheet��Ҳ�������һ��Sheet
		
		this.workbook.setSheetName(this.currentSheetId, sheetName + plusName);
		
		return result;
	}
	
	/**
	 * �õ���Sheet��Ŀǰ��Ҫ��ȡ��һ����ϸ��Ϣ��ĳ����Ԫ����к�
	 */
	private int getDetailCellRowId(HSSFSheet sheet, int lineId, CellExportRule rule){
		if(sheet == null || lineId < 0 || rule == null){
			return -1;
		}

		int rowId = rule.getRowId(); // ���ֶε���ʼ�к�
		
		String validRange = rule.getValidRange();
		if(validRange == null || "".equals(validRange.trim())){
			rowId = -1;
		}
		else if("this".equals(validRange) && lineId > 0){
			rowId = -1;
		}
		else if("all".equals(validRange)){
			rowId = rowId + lineId;
		}
		else if("row+all".equals(validRange)){
			rowId = rowId + lineId;
		}
		else if("row-all".equals(validRange)){
			rowId = rowId - lineId;
		}
		else if(validRange.indexOf("row+") >= 0){
			int n = 0;
			
			try{
				n = Integer.parseInt(validRange.substring(validRange.indexOf("row+") + "row+".length()));
			}
			catch(Exception e){
			}
			
			rowId = rowId + n;
		}
		else if(validRange.indexOf("row-") >= 0){
			int n = 0;
			
			try{
				n = Integer.parseInt(validRange.substring(validRange.indexOf("row-") + "row-".length()));
			}
			catch(Exception e){
			}
			
			rowId = rowId - n;
		}
		
		// �ж��Ƿ񳬹���EXCEL���������к�
		if(rowId > ExcelUtil.MAX_ROW_ID_IN_SHEET){
			rowId = -1;
		}
		
		return rowId;
	}
	
	/**
	 * �õ���Sheet��Ŀǰ��Ҫ��ȡ��һ����ϸ��Ϣ��ĳ����Ԫ����к�
	 */
	private short getDetailCellColumnId(HSSFSheet sheet, int lineId, CellExportRule rule){
		if(sheet == null || lineId < 0 || rule == null){
			return -1;
		}

		short columnId = rule.getColumnId();
		
		String validRange = rule.getValidRange();
		if(validRange == null || "".equals(validRange.trim())){
			columnId = -1;
		}
		else if("this".equals(validRange) && lineId > 0){
			columnId = -1;
		}
		else if("all".equals(validRange)){
			columnId = (short)(columnId + lineId);
		}
		else if("column+all".equals(validRange)){
			columnId = (short)(columnId + lineId);
		}
		else if("column-all".equals(validRange)){
			columnId = (short)(columnId - lineId);
		}
		else if(validRange.indexOf("column+") >= 0){
			int n = 0;
			
			try{
				n = Integer.parseInt(validRange.substring(validRange.indexOf("column+") + "column+".length()));
			}
			catch(Exception e){
			}
			
			columnId = (short)(columnId + n);
		}
		else if(validRange.indexOf("column-") >= 0){
			int n = 0;
			
			try{
				n = Integer.parseInt(validRange.substring(validRange.indexOf("column-") + "column-".length()));
			}
			catch(Exception e){
			}
			
			columnId = (short)(columnId - n);
		}
		
		// �ж��Ƿ񳬹���EXCEL���������к�
		if(columnId > ExcelUtil.MAX_COLUMN_ID_IN_SHEET){
			columnId = -1;
		}
		
		return columnId;
	}
	
	/**
	 * �õ���Sheet��Ŀǰ��Ҫ��ȡ��һ����ϸ��Ϣ�е�ĳ����Ԫ��
	 */
	private HSSFCell getDetailCellOfSheet(HSSFSheet sheet, int lineId, CellExportRule rule){
		if(sheet == null || lineId < 0 || rule == null){
			//System.out.println("Detail No." + lineId + " of " + rule.getCellName() + "is empty because sheet == null || lineId < 0 || rule == null."); // (*)
			return null;
		}

		int rowId = this.getDetailCellRowId(sheet, lineId, rule);
		short columnId = this.getDetailCellColumnId(sheet, lineId, rule);
		if(rowId < 0 || columnId < 0){
			//System.out.println("Detail No." + lineId + " of " + rule.getCellName() + "is empty because rowId < 0 || columnId < 0"); // (*)
			return null;
		}

		HSSFCell cell = ExcelUtil.getCell(sheet, rowId, columnId);

		return cell;
	}
	
	
	public int getLineType() {
		return lineType;
	}

	public void setLineType(int lineType) {
		this.lineType = lineType;
	}

	public short getDefaultColumnWidth() {
		return defaultColumnWidth;
	}

	public void setDefaultColumnWidth(short defaultColumnWidth) {
		this.defaultColumnWidth = defaultColumnWidth;
	}
	
	public boolean isAutoAdjustUndefinedColumnWidth() {
		return autoAdjustUndefinedColumnWidth;
	}

	public void setAutoAdjustUndefinedColumnWidth(
			boolean autoAdjustUndefinedColumnWidth) {
		this.autoAdjustUndefinedColumnWidth = autoAdjustUndefinedColumnWidth;
	}

	public String getExportFilePath() {
		return exportFilePath;
	}
	
	/**
	 * �ڿ���̨��ӡ�����Ѽ��ص���֤���򣬲�����
	 */
	private void printRules(){
		this.templateExportRule.print();
		this.printRulesInMap(this.headDataRuleMap);
		this.printRulesInMap(this.detailDataRuleMap);
	}
	
	/**
	 * �ڿ���̨��ӡMap�е�������֤���򣬲�����
	 */
	private void printRulesInMap(Map ruleMap){
		Set entrySet = ruleMap.entrySet();
		Iterator it = entrySet.iterator();
		while(it.hasNext()){
			Map.Entry entry = (Map.Entry)it.next();
			CellExportRule rule = (CellExportRule)entry.getValue();
			rule.print();
		}
	}



	public HSSFWorkbook getWorkbook() {
		return workbook;
	}

	public void setWorkbook(HSSFWorkbook workbook) {
		this.workbook = workbook;
	}



	public HSSFSheet getCurrentSheet() {
		return currentSheet;
	}



	public void setCurrentSheet(HSSFSheet currentSheet) {
		this.currentSheet = currentSheet;
	}



	public HSSFRow getRow(int i) {
		return this.currentSheet.getRow(i);
	}
}
